import { graphql } from 'gatsby';

import Callout from '../../components/Callout';
import ComponentApi from '../../components/ComponentApi';
import ReactPlayground from '../../components/ReactPlayground';

import ValidationFormik from '../../examples/Form/ValidationFormik';
import ValidationInputGroup from '../../examples/Form/ValidationInputGroup';
import ValidationNative from '../../examples/Form/ValidationNative';
import ValidationTooltips from '../../examples/Form/ValidationTooltips';

# Validation

<p className="lead">
  Provide valuable, actionable feedback to your users with HTML5 form
  validation, via browser default behaviors or custom styles and JavaScript.
</p>

## Native HTML5 form validation

For native HTML form validation–[available in all our supported browsers](https://caniuse.com/#feat=form-validation),
the `:valid` and `:invalid` pseudo selectors are used to apply validation
styles as well as display feedback messages.

Bootstrap scopes the `:valid` and `:invalid` styles to parent `.was-validated`
class, usually applied to the `<Form>` (you can use the `validated` prop
as a shortcut). Otherwise, any required field without a value shows up
as invalid on page load. This way, you may choose when to activate them
(typically after form submission is attempted).

<Callout>
  Watch out! Browsers provide their own validation UI by default on{' '}
  <code>form</code>s. You can disable the default UI by adding the HTML{' '}
  <code>noValidate</code> attribute to your <code>{'<Form>'}</code> or{' '}
  <code>{'<form>'}</code> element.
</Callout>

<ReactPlayground codeText={ValidationNative} />

## Form libraries and server-rendered styles

It's often beneficial (especially in React) to handle form validation
via a library like Formik, or react-formal. In those cases, `isValid`
and `isInvalid` props can be added to form controls to manually apply
validation styles. Below is a quick example integrating with
[Formik](https://github.com/jaredpalmer/formik).

<ReactPlayground codeText={ValidationFormik} />

## Tooltips

If your form layout allows it, you can use the `tooltip` prop to display
validation feedback in a styled tooltip. Be sure to have a parent with
`position: relative` on it for tooltip positioning. In the example below,
our column classes have this already, but your project may require an
alternative setup.

<ReactPlayground codeText={ValidationTooltips} />

## Input group validation

To properly show rounded corners in an `<InputGroup>` with validation,
the `<InputGroup>` requires the `hasValidation` prop.

<ReactPlayground codeText={ValidationInputGroup} />

## API

<ComponentApi
  metadata={props.data.Feedback}
  exportedBy={props.data.FormControl}
/>

export const query = graphql`
  query FormValidationQuery {
    Form: componentMetadata(displayName: { eq: "Form" }) {
      ...ComponentApi_metadata
    }
    Feedback: componentMetadata(displayName: { eq: "Feedback" }) {
      ...ComponentApi_metadata
    }
  }
`;
